package at.ac.tuwien.dse.health.security.authentication;

import at.ac.tuwien.dse.health.entity.Account;
import at.ac.tuwien.dse.health.entity.Doctor;
import at.ac.tuwien.dse.health.entity.Hospital;
import at.ac.tuwien.dse.health.entity.Patient;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.springframework.beans.BeanUtils;

import java.io.Serializable;
import java.util.Collections;
import java.util.Map;

/**
 * Processes an authentication request by performing a lookup within the provided credentials.
 *
 * @author Bernhard Nickel
 * @author Gregor Schauer
 * @author Dominik Strasser
 */
public class SimpleAuthenticationManager implements AuthenticationManager {
	Map<String, String> patientCredentials = Collections.emptyMap();
	Map<String, String> doctorCredentials = Collections.emptyMap();
	Map<String, String> hospitalCredentials = Collections.emptyMap();

	@Override
	public Account authenticate(String username, String password) {
		if (password.equals(patientCredentials.get(username))) {
			return createAccount(Patient.class, username, password);
		} else if (password.equals(doctorCredentials.get(username))) {
			return createAccount(Doctor.class, username, password);
		} else if (password.equals(hospitalCredentials.get(username))) {
			return createAccount(Hospital.class, username, password);
		}
		return null;
	}

	/**
	 * Creates a new account providing a simple user instance of the given type.
	 *
	 * @param userType the type of the user
	 * @param username the username of the account
	 * @param password the password of the account
	 * @return the account
	 */
	private Account createAccount(Class<? extends Serializable> userType, String username, String password) {
		Serializable role = BeanUtils.instantiateClass(userType);
		Account account = new Account();
		account.setUsername(username);
		account.setPassword(password);
		try {
			BeanUtilsBean.getInstance().setProperty(account, userType.getSimpleName().toLowerCase(), role);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return account;
	}

	public void setPatientCredentials(Map<String, String> patientCredentials) {
		this.patientCredentials = patientCredentials;
	}

	public void setDoctorCredentials(Map<String, String> doctorCredentials) {
		this.doctorCredentials = doctorCredentials;
	}

	public void setHospitalCredentials(Map<String, String> hospitalCredentials) {
		this.hospitalCredentials = hospitalCredentials;
	}
}
